function request(obj) {
  return new Promise((resolve, reject) => {
    if (obj.url === undefined) throw new Error('请求路径不能为空！')

    if (typeof obj.url != 'string') throw new Error('请求卢金虎错误！')

    if (obj.dataType === undefined) obj.dataType = 'json'

    if (obj.method === undefined) obj.method = 'get'

    if (obj.method.toLowerCase() != 'get' && obj.method.toLowerCase() != 'post' && obj.method.toLowerCase() != 'put' && obj.method.toLowerCase() != 'delete') throw new Error('请求方式不正确！')

    if (obj.async === undefined) obj.async = true

    if (typeof obj.async != 'boolean') throw new Error('请输入布尔值！')

    let data
    // 如果有参数，将其他形式参数都设置为字符串形式
    if (obj.data != undefined) {
      if (Object.prototype.toString.call(obj.data) === '[object Object]') {
        let arr = []
        for (let key in obj.data) {
          arr.push(key + '=' + obj.data[key])
        }
        data = arr.join('&')
      } else if (Object.prototype.toString.call(obj.data) === '[object String]') {
        data = obj.data
      } else {
        console.log(Object.prototype.toString.call(obj.data))
        throw new Error('data是对象或许字符串')
      }

      if (obj.method.toLowerCase() === 'get') {
        obj.url += '?' + data
      }
    }

    let xhr = new XMLHttpRequest;
    xhr.open(obj.method, obj.url, obj.async)

    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        if (xhr.status >= 200 && xhr.status < 300) {
          let res
          switch (obj.dataType) {
            case 'xml':
              res = xhr.responseXML
              break
            case 'json':
              res = JSON.parse(xhr.responseText)
              break
            case 'text':
              res = xhr.responseText
              break
            default:
              throw new Error('dataType必须是json/text/xml')
          }
          resolve(res)
        } else {
          reject('请求错误！')
        }
      }
    }

    for (let key in obj.headers) xhr.setRequestHeader(key, obj.headers[key])

    // post请求携带参数
    if (obj.method.toLowerCase() === 'post' && data) {
      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
      xhr.send(data)
      return
    }
    // 将send可以放在最后
    xhr.send()
  })
}
